import { CSSProperties, FC, ReactNode } from 'react';
import { EditableExcelTableI18n } from '../i18n';

// 组件内部使用的类型：去除 'x-' 前缀，使用简洁字段
export type EditorType = 'text' | 'select' | 'time' | 'number' | 'textarea' | 'dateRange' | 'radio';

export interface BaseColumn {
    title: string;
    dataIndex: string;
    width?: number;
    required?: boolean;
    type: EditorType;
}

export interface InputColumn extends BaseColumn {
    type: 'text';
}

export interface SelectColumn extends BaseColumn {
    type: 'select';
    // 与根目录 type.ts 保持一致：options 为字符串数组
    options?: string[];
}

export interface OtherColumn extends BaseColumn {
    type: Exclude<EditorType, 'select' | 'text'>;
}

export type TColumn = InputColumn | SelectColumn | OtherColumn;

export type TDataRow<T extends TColumn = TColumn> = {
    [K in T extends { dataIndex: string } ? T['dataIndex'] : never]?: string;
} & {
    // 如果有错误就返回 字段 _errors
    _errors?: Array<{
        // 如果整行错误就没有 column 字段，如果有就是单行错误
        // 列号，从 0[下标] 开始
        column?: number;
        errorMessage?: string;
    }>;
};

// 前端主数据结构
export interface ExcelSheetData<T extends TColumn = TColumn> {
    columns: T[];
    data: TDataRow<T>[];
}

export type ControlledEditorProps = {
    className?: string;
    value: any;
    // 关闭编辑器【一般失焦触发】
    onClose?: (obj: { type?: 'leaveEditor' & string; value?: any }) => void;
    // 改变过程的值，如果没有提供，则不触发和顶部的共享数据
    onChange?: (value: any) => void;
    // 是否即刻更新【鼠标失焦后， 如果编辑框还在当前，是否立刻更新】
    updateImmediately?: boolean;
};

export type EditableExcelTableProps<C extends TColumn = TColumn> = {
    /** ref */
    viewportRef?: React.RefObject<HTMLDivElement>;

    /** 表格标题 */
    sheetTitle?: string | ReactNode;

    /** 表格标题样式 */
    sheetTitleStyle?: CSSProperties;

    /** 表格数据 */
    sheetData: ExcelSheetData<C>;

    /** 头部操作按钮 */
    headerActions?: ReactNode;

    /** 国际化配置 */
    i18n?: {
        locale?: string;
        messages?: Partial<EditableExcelTableI18n>;
    };

    /**
     * 表格主体容器样式【主要设置高度】 针对非虚拟滚动
     * 虚拟滚动 由虚拟滚动 virtualization 的 rowHeight 和 overscan 决定
     */
    tableBodyContainerStyle?: CSSProperties;
    /** 虚拟滚动入参 */
    virtualization?: {
        enabled: boolean;
        rowHeight?: number;
        overscan?: number;
    };

    /** 可插拔编辑器（受控接口：value + onClose） */
    editorRenderers?: Partial<
        Record<
            EditorType,
            {
                editableRender?: React.ComponentType<ControlledEditorProps>;
                readonlyRender?: React.ComponentType<Pick<ControlledEditorProps, 'value' | 'className'>>;
            }
        >
    >;
};

export type EditableExcelTableRef<C extends TColumn = TColumn> = {
    /** 获取表格数据 */
    getData: () => ExcelSheetData<C>;
};
